iT邦幫忙

2026 iThome 鐵人賽

DAY 26
0
AI Engineering

生活中的 AI 應用:我在家用 NAS 養了一隻 Agent,幫我看盤、顧家、盯備考——30 天自架實錄系列 第 26

Day 26:自架系統資安自白——token 進了 git、密碼寫進 Markdown

  • 分享至 

  • xImage
  •  

寫完監控和評分那幾篇後,我心血來潮給系統做了一輪安全審查。想像中的產出是「檢查完畢,體質良好」,實際的產出是一份讓我不太想給人看的清單:最大的幾個漏洞,全部是我自己親手埋的。

沒有駭客、沒有 0-day、沒有供應鏈攻擊。就是一個知道所有最佳實踐的工程師,在「反正是自己家的系統」的心態下,把上班時絕不會犯的錯,在家裡犯好犯滿。

今天這篇是自白書。三個真實的錯誤、它們為什麼會發生、怎麼修,以及幾條通則。先說好:本篇講的是原則和錯誤模式,現存系統的具體配置不會出現在文章裡——這本身就是其中一條原則。

錯誤一:憑證檔被 git 追蹤

https://ithelp.ithome.com.tw/upload/images/20260822/20182865tWF5R6ug4X.png

審查的第一站是 workspace 的 git 狀態。一跑 git ls-files,心涼了半截:一份 API 憑證的 JSON 檔,安安穩穩地躺在版本控制裡,跟著每一次 commit 被完整保存。

它怎麼進去的?回憶起來平淡無奇:某天為了讓 Agent 串接外部服務,把憑證檔放進 workspace(因為容器掛載的就是這個目錄,放這裡最方便);某天想給 workspace 上版本控制,git add -A 一把梭;憑證就這樣入庫了。兩個「當下都合理」的動作,交叉出一個漏洞。

修復比想像中麻煩,因為 git 的歷史是永久的——把檔案從最新 commit 刪掉毫無意義,任何人翻歷史都撈得回來。完整的處置是三步:

# 1. 讓 git 忘記它(但保留本機檔案)
git rm --cached credentials.json
echo "credentials.json" >> .gitignore

# 2. 清洗歷史(用 git-filter-repo 或 BFG 重寫所有 commit)
git filter-repo --path credentials.json --invert-paths

# 3. 最重要的一步:把這份憑證「作廢重發」
#    ——歷史清洗只能防未來,你必須假設它已經洩漏

第三步是多數人會偷懶跳過的:**只要憑證曾經進過版本庫,就當它已經洩漏,撤銷重發。**清洗歷史是打掃現場,換鎖才是止損。

錯誤二:PAT 嵌在 git remote URL 裡

第二個發現在 git remote -v 的輸出裡:remote URL 長這樣——

https://<username>:ghp_xxxxxxxxxxxx@github.com/...

一個 Personal Access Token,明文嵌在 URL 中。這是很多教學文章教的「免輸入密碼」快捷法,方便到令人上癮。問題是這個 URL 會出現在 .git/config(明文檔案)、shell 歷史、任何 git remote -v 的輸出——包括你截圖貼文、錄影 demo、把 log 貼給別人 debug 的時候。而我的 workspace 又被同步工具複製到多台機器,等於每台同步節點上都有一份明文 token

修法是換掉認證通道,讓 URL 裡不再有秘密:

# 改用 credential manager 保管(或改走 SSH key)
git remote set-url origin https://github.com/<user>/<repo>.git
git config credential.helper manager   # token 進系統的憑證保險箱
# 然後:舊 token 撤銷重發(理由同上——它已經到處都是了)

錯誤三:密碼明文寫進 Markdown 筆記

第三個最難堪。全文搜尋 workspace 裡的敏感關鍵字(passwordtokensecret……),在某份服務筆記裡撈到一行:「管理介面密碼:XXXX」。

為什麼致命?因為這套系統的核心設計就是「所有 Markdown 都會被 LLM 讀取」。筆記是 Agent 的記憶、會被 dreaming 整合、會被同步到多台裝置、片段可能被引用進報告——甚至被我複製貼上進這個系列的草稿。在傳統筆記軟體裡寫密碼只是壞習慣;在 Agent 系統的 workspace 裡寫密碼,等於把密碼放進一條你無法完全預測的資料流。

修復動作:改密碼、筆記改寫成「密碼在密碼管理器,條目名 XX」。真正的秘密只活在兩個地方——密碼管理器,或部署層注入的環境變數(Day 19 講 HA token 時用過的做法)。LLM 可讀層裡只放「指標」,不放「值」。

三個錯誤的共同根因

錯誤 表面原因 真正根因
憑證進 git git add -A 憑證和資料放在同一個目錄層
PAT 進 URL 教學抄來的快捷法 圖方便,沒想過 URL 是明文配置
密碼進筆記 隨手記 沒意識到「筆記」在這系統裡是資料流

共同點是:每個錯誤在犯下的當下都毫無感覺,因為家用系統沒有 security review、沒有掃描 pipeline、沒有同事的白眼。企業環境靠制度擋掉的東西,個人環境只剩你的習慣——而習慣在「就自己用」的心態下最容易鬆動。事實上我的 workspace 根本不是「就自己用」:它同步多台機器、對外開了 Web 介面、每天被 LLM 讀寫。攻擊面早就是分散式系統等級,防護心態還停在單機。

再誠實一層:「反正是私有 repo」是這一切最好的安眠藥。倉庫私有、機器自己的——所以憑證檔先放著、歷史殘留以後再清,「先隨便弄,後面再慢慢搞」。這個心態的問題不在當下(私有 repo 確實沒別人看得到),在它假設了「以後」真的會來:等你想清歷史的那天,那把金鑰已經跟著同步工具住進每一台機器、跟著備份躺在你早就忘記的角落。私有降低的是被看見的機率,不是擴散的速度。

對標我現在的管理辦法,同一件事長這樣:

  • 機密只有兩個合法住所:密碼管理器、部署層的環境變數(不進版控)——其他任何地方出現都算事故,不算「先放一下」
  • 兩道排除閘門都要設.gitignore 擋版本庫、同步工具的排除規則擋擴散——它們互相獨立,設了一個不會自動有另一個(下一段那個盲區就是這麼來的)
  • 掃描例行化且含未追蹤檔:CI 擋新增、每日掃存量,命中即告警
  • 進過版控一律作廢重發——「私有」不改變「假設已洩漏」的處置
  • 歷史殘留列管,不假裝不存在:私有 repo 的舊歷史可以排期改寫,但它得躺在待辦清單上有編號、有日期,而不是躺在「以後再說」裡沒人記得

從「先隨便弄」到這五條,中間隔的不是技術,是三次被自己嚇到。

發布任何內容前,另有一道機敏清單把關(這個系列每篇文末的 checklist 就是它)——資安不是狀態,是重複執行的動作。

而上面第三條那道例行掃描,後來又補了我一課。它最初只掃 git 追蹤的檔案——聽起來合理,掃版本庫嘛。結果幾份含舊憑證的檔在磁碟上躺了兩個月沒人發現:.gitignore 擋在版本庫外的檔,恰好也被掃描器擋在視野外——擋住 git 的那條規則,同時讓警察看不見它。而同步工具不讀 .gitignore,那些檔照樣被複製到每一台機器。.gitignore 和同步排除規則是兩道各自獨立的閘門,「git 裡看不到」跟「沒有外流」是兩件事。現在掃描器連未追蹤檔一起掃——**防線的盲區,往往正好在另一道防線的陰影裡。**順帶一提,這輪審查用到的工具毫無高深可言——git ls-filesgit remote -v、全文關鍵字搜尋,三個指令就挖出三個洞。挖洞的門檻從來不高,高的是願意對自己系統動手的自覺。

小結+明日預告

三條通則帶走:秘密永遠不進版本庫(進過就作廢重發)、秘密不進 LLM 可讀層(只放指標不放值)、以及——用審查對抗心態,因為「自己家的系統」四個字就是最大的漏洞。

自白完畢,明天回到建設性的主題:MCP Server 工具層。在桌面 AI 輸入一句「重啟 CLI 容器」,NAS 上的 docker restart 就自己跑完了——這中間發生了什麼,以及哪些操作我刻意「不」做成工具。


🔑 這篇的關鍵字
秘密管理:只進環境變數 / .env + .gitignore不進版本庫、不進 LLM 可讀層
LLM 可讀層只放指標不放值(例:記憶檔寫「token 已輪替」,不寫 token 本身)
外洩後的正確順序:先撤銷再清理——git history 清乾淨了,外流的那把鑰匙還是有效的
防線的盲區在另一道防線的陰影裡.gitignore 擋住的檔,掃描器也看不見,但同步工具照搬——掃描要含未追蹤檔
權限按破壞半徑分級:唯讀 / 可寫 / 可刪 / 可改設定,不是一把 admin 走天下


我是一名金融業資訊工程師,這是我半年來在家自架 AI Agent 系統的實錄。


上一篇
Day 25:我的系統每月考試——85 分,B 級
下一篇
Day 27:一句話重啟容器——MCP Server 工具層實作
系列文
生活中的 AI 應用:我在家用 NAS 養了一隻 Agent,幫我看盤、顧家、盯備考——30 天自架實錄30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言